#include "FileSystem.h"
#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
struct FileSystem
{
    char *dirPath;
};

// 文件系统初始化
FileSys * FileSystemInit(const char * DirPath)
{
    FileSys* fs = (FileSys* )malloc(sizeof(DirPath));
    if(fs == NULL)
    {
        printf("FileSystemInit malloc error!\n");
    }

    DIR *dir;
    if( (dir = opendir(DirPath)) == NULL)
    {
        if(mkdir(DirPath,0777) != 0)
        {
            perror("mkdir");
            free(fs);
            return NULL;
        }
        fs->dirPath = strdup(DirPath);
        return fs;
    }
    else
    {
        closedir(dir);
        fs->dirPath = strdup(DirPath);
        return fs;
    }
}

bool CreateNewDirInFs(FileSys * fs, const char * DirName)
{
    char DirPath[1024] = {0};
    sprintf(DirPath,"%s/%s",fs->dirPath,DirName);
    if(mkdir(DirPath,0777) != 0)
    {
        perror("mkdir");
        return false;
    }
    return true;
}

// 删除根目录下的文件夹
bool DeleteDirInFs(FileSys * fs, const char * DirName)
{
    char DirPath[1024] = {0};
    sprintf(DirPath,"%s/%s",fs->dirPath,DirName);// 
    if(rmdir(DirPath) != 0)
    {
        perror("rmdir");
        return false;
    }
    return true;
}

// 判断根目录下的文件夹是否存在
bool isDirExist(FileSys * fs, const char * DirName)
{
    DIR *dir = opendir(fs->dirPath);
    if(dir == NULL)
    {
        perror("isDirExist opendir");
        return false;
    }

    struct dirent * entry;
    while( (entry = readdir(dir)) != NULL)
    {
        if(strcmp(entry->d_name, DirName) == 0)
        {
            closedir(dir);
            return true;
        }
    }
    closedir(dir);
    return false;
}

// 在根目录下的文件夹内写入文件数据
void WriteFileToFs(FileSys *fs,const char * DirName,const char *fileName,void *p,size_t size)
{
    char filePath[1024] = {0};
    sprintf(filePath,"%s/%s/%s",fs->dirPath,DirName,fileName);// 
    FILE * f = fopen(filePath,"a");// 以追加模式写
    fwrite(p,size,1,f);// 写 f 个字节，写一次
    fclose(f);
}

// 获取文件的具体信息: 这里主要是大小
char* GetFileSize(const char * DirPath, const char *fileName)
{
    char filePath[1024] = { 0 };
    sprintf(filePath,"%s/%s", DirPath, fileName);// 
    struct stat st;//
    stat(filePath,&st);// 获取文件信息

    char size[20] = { 0 };
    sprintf(size,"%ld",st.st_size);// 格式化输出: 文件大小。 将文件大小转换为字符串
    return strdup(size);// 局部变量不能返回
}

// 查看根目录下的文件夹的文件列表：能回传的只能是char *
char * GetFileList(FileSys *fs, const char *DirName)
{
    char list[1024] = { 0 };
    char DirPath[1024] = { 0 };
    sprintf(DirPath, "%s/%s", fs->dirPath, DirName);// 
    DIR *dir = opendir(DirPath);
    if (dir == NULL)
    {
        perror("GetFileList opendir");
        return NULL;
    }

    struct dirent *entry;// 获取文件
    while ((entry = readdir(dir)) != NULL)
    {
        // 滤掉了"."和".."这两个特殊的目录条目，以便处理目录中的实际内容
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
            continue;

        char *size = GetFileSize(DirPath, entry->d_name);// 获取文件大小
        strcat(list, entry->d_name);
        strcat(list, ";"); // 以分号隔开
        strcat(list, size);
        strcat(list, ",");
        free(size);
    }
    if (strlen(list) == 0)// 没有文件
    {
        closedir(dir);
        return NULL;
    }
    list[strlen(list) - 1] = '\0';// 去掉最后一个 ,
    closedir(dir);
    return strdup(list);// 局部变量不能返回
}

char *GetServerFileDirPath(FileSys *fs, const char *username, const char *filename)
{
    char filePath[32] = {0};
    sprintf(filePath,"%s/%s/%s",fs->dirPath,username,filename);
    return strdup(filePath);
}